<template>
  <Card class="category" :bordered="false">
    <template #title> 分类列表 （{{ categories.pagination?.total ?? '-' }}） </template>
    <template #extra>
      <Button type="primary" size="small" @click="createNewData">
        <PlusOutlined />创建新分类
      </Button>
    </template>
    <Space class="toolbar">
      <Space>
        <Button type="primary" :loading="loading.state.value" @click="fetchData">
          <template #icon>
            <ReloadOutlined />
          </template>
          刷新
        </Button>
      </Space>
    </Space>
    <Divider />
    <Spin :spinning="loading.state.value">
      <Tree
        class="tree"
        block-node
        auto-expand-parent
        default-expand-all
        :checkable="false"
        show-line
        :show-icon="false"
        :selectable="false"
        :tree-data="[
          ...getAntdTreeByTree({
            tree: categories.tree,
            valuer: (c) => c._id,
          }),
        ]"
      >
        <template #title="{ dataRef }">
          <div class="categoryNode">
            <div class="content">
              <Space class="title">
                <TypographyText strong>
                  {{ dataRef.data?.name }}
                </TypographyText>
                <Divider type="vertical" />
                <TypographyText type="secondary">
                  {{ dataRef.data?.slug }}
                </TypographyText>
                <Divider type="vertical" />
                <TypographyText type="secondary">
                  {{ dataRef.data?.articles_count }}篇
                </TypographyText>
              </Space>
              <div>
                <TypographyText type="secondary">
                  {{ dataRef.data?.description }}
                </TypographyText>
              </div>
            </div>
            <div class="actions">
              <Button size="small" type="text" @click="editData(dataRef.data?._id!)">
                <template #icon>
                  <EditOutlined />
                </template>
                编辑
              </Button>
              <Button size="small" type="text" danger @click="handleDelete(dataRef.data?._id!)">
                <template #icon>
                  <DeleteOutlined />
                </template>
                删除
              </Button>
              <Button
                size="small"
                type="link"
                target="_blank"
                :href="getBlogCategoryUrl(dataRef.data?.slug)"
              >
                <template #icon>
                  <LinkOutlined />
                </template>
                查看
              </Button>
            </div>
          </div>
        </template>
      </Tree>
    </Spin>
    <EditModal
      :title="activeEditData ? '编辑分类' : '新分类'"
      :visible="isVisibleModal"
      :categories="categories.data"
      :tree="
        getAntdTreeByTree({
          tree: categories.tree,
          valuer: (c) => c._id,
          disabledWhen: (c) => {
            if (c._id === activeEditData?._id) {
              return true
            }
            if (c.pid === activeEditData?._id) {
              return true
            }
            return false
          },
        })
      "
      :category="activeEditData"
      :onCancel="closeModal"
      :onSubmit="handleSubmit"
    />
  </Card>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { Button, Card, Divider, Modal, Space, Spin, Tree, TypographyText } from 'ant-design-vue'
import {
  PlusOutlined,
  EditOutlined,
  LinkOutlined,
  DeleteOutlined,
  ReloadOutlined,
} from '@ant-design/icons-vue'

import type { ResponsePaginationData } from '@/constants/request'
import type { Category as CategoryType } from '@/constants/category'
import EditModal from './editModal.vue'
import {
  getAntdTreeByTree,
  getCategories,
  putCategory,
  deleteCategory,
  createCategory,
} from '@/store/category'
import { getBlogCategoryUrl } from '@/transformers/url'
import { useLoading } from '@/handcer'

// 列表数据
const loading = useLoading()
const categories = reactive<ResponsePaginationData<CategoryType> & { tree: Array<CategoryType> }>({
  tree: [],
  data: [],
  pagination: void 0,
})

// 弹窗
const activeEditDataId = ref<string | null>(null)
const isVisibleModal = ref<boolean>(false)
const activeEditData = computed(() => {
  const id = activeEditDataId.value
  return id !== null ? categories.data.find((c) => c._id === id)! : null
})
const closeModal = () => {
  isVisibleModal.value = false
}

// 编辑创建
const editData = (id: string) => {
  activeEditDataId.value = id
  isVisibleModal.value = true
}
const createNewData = () => {
  activeEditDataId.value = null
  isVisibleModal.value = true
}

const fetchData = () => {
  return loading.promise(getCategories({ per_page: 50 })).then((response) => {
    categories.data = response.data
    categories.pagination = response.pagination
    categories.tree = response.tree
  })
}

// 单个删除
const handleDelete = (id: string) => {
  Modal.confirm({
    title: '确定要删除公告吗？',
    content: '删除后不可恢复',
    centered: true,
    onOk: () => {
      deleteCategory(id).then(() => {
        fetchData()
      })
    },
  })
}

// 提交表单
const handleSubmit = (category: CategoryType) => {
  if (activeEditData.value) {
    putCategory({
      ...activeEditData.value,
      ...category,
    }).then(() => {
      closeModal()
      fetchData()
    })
  } else {
    createCategory(category).then(() => {
      closeModal()
      fetchData()
    })
  }
}

onMounted(() => {
  fetchData()
})
</script>

<style lang="less" scoped>
.category {
  .toolbar {
    display: flex;
    justify-content: space-between;

    .select {
      width: 130px;
    }
    .search {
      width: 200px;
    }
  }

  @paddingSize: 10px;
  .categoryNode {
    width: 100%;
    padding: @paddingSize;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-radius: @radius;
    &:hover {
      background-color: @module-hover-bg;
    }

    .content {
      .title {
        width: 100%;
        margin-bottom: 5px;
      }
    }
  }

  .tree {
    margin-bottom: -1rem;
  }

  :deep(.ant-tree-treenode) {
    margin-bottom: 1rem;
  }

  :deep(.ant-tree-switcher) {
    padding-top: @paddingSize;
  }
}
</style>
